<?php
/***
*	Classe : ecForm
*
*   Notes : La classe ecForm est la classe qui gère la génération des formulaires. C'est celle qu'il faut instancier dans tous les cas.
*
*
*/

class ecForm
{
	/***
	* Le nom unique du formulaire
	* @var protected string nom
	*/
	protected $nom;

	/***
	* La méthode d'envoi des données du formulaire (POST ou GET)
	* @var protected string methode
	*/
	protected $methode;

	/***
	* La page de traitement du formulaire. Par défaut, aucune action n'est effectuée si le fichier n'existe pas.
	* Modifier le paramètre $checkAction du constructeur pour.
	* @var protected string nom
	*/
	protected $action;

	/***
	* Indique si les données sortantes du formulaire doivent être traitées par htmlspecialchars()
	* @var protected bool protectHtml
	*
	*/
	protected $protectHtml;

	/***
	* L'array contenant les objets, éléments du formulaires, instanciés depuis la méthode add()
	* @var protected array elements
	*/
	private $elements = array();


	/***
	* __construct
	*
	* Le constructeur de la classe ZForm
	*
	* @var string $nom = NULL				Le nom unique du formulaire
	* @var string $methode = POST			La méthode utilisée par le formulaire pour transférer les données
	* @var string $action = NULL			La page de traitement du formulaire
	* @var bool $checkAction = FALSE		Le boléen indiquant si le constructeur doit afficher une erreur en cas d'indication d'une page de traitement inexistante
	*/
	public function __construct($nom=NULL, $methode = 'POST', $action = NULL, $checkAction = false)
	{
		$this->nom = $nom;
		$this->methode = $methode;

		if($checkAction && !file_exists($action))
		{
      trigger_error('La page de traitement définie n\'existe pas.', E_USER_WARNING);
		}
		$this->action = $action;

		if(get_magic_quotes_gpc())
		{
			$_POST = array_map('stripslashes', $_POST);
			$_GET = array_map('stripslashes', $_GET);
			$_COOKIE = array_map('stripslashes', $_COOKIE);
		}

		$this->protectHtml = true;
	}

	/**
	* __toString()
	*
	* Génère le formulaire lors d'un echo de l'instance de la classe
	*
	* @return string       Contient le html du formulaire généré
	*/
	public function __toString()
	{
		if(empty($this->elements))
      return 'Aucun élement dans le formulaire';

		$out = '';
		$out .= "\n<p>\n";
		$out .= '<form action="'.$this->action.'" method="'.$this->methode.'" id="'.$this->nom.'" enctype="multipart/form-data">';

    foreach($this->elements as $element)
		{
			$out .= $element->getHtml()."\n";
		}

		$out .= '<input type="submit" name="submit" id="submit" />'."\n".'</form>'."\n".'</p>';

    return $out;
	}

	/**
	* add($type)
	*
	*  Ajoute un champ en instanciant la classe correspondante et stocke l'objet instancié dans le tableau elements
	*
	* @var string $type					   Indique la nature du champ à ajouter
	* @return mixed 					   Object si le type est reconnu par la classe, bool (FALSE) dans le cas contraire
	*/
	public function add($type)
	{
		$rempls = array('Text' => 'ecTextInput',
                    'Email' => 'ecMailInput',
                    'Date' => 'ecDateInput',
                    'Checkbox' => 'ecCheckBox',
                    'Radio' => 'ecRadio',
                    'Select' => 'ecSelectList',
                    'Password' => 'ecPasswordInput',
                    'Hidden' => 'ecHiddenField',
                    'Textarea' => 'ecTextareaInput',
                    'File' => 'ecFileInput');

		foreach($rempls as $i => $a)
		{
			$type = preg_replace('#^'.$i.'$#isU', $a, $type);
		}

    if(!($obj = new $type()))
      return false;
		$this->elements[] = $obj;
      return $obj;
	}

	/**
	*
	*  Renvoie TRUE si le formulaire a été soumis, FALSE dans le cas contraire
	*
	* @return bool
	*/
	public function isSubmitted()
	{
		return (isset($_POST['submit']));
	}

	/**
	*
	*  Renvoie TRUE si le formulaire a été soumis et s'il est conforme aux restrictions imposées par l'utilisateur
	*
	* @var array $array		L'array dans lequel chercher et vérifier la validité des valeurs (le plus souvent $_POST ou $_GET)
	* @return bool
	*/
	public function isValid($array)
	{
		if(empty($this->elements) OR !$this->isSubmitted())
      return FALSE;

		foreach($this->elements as $obj)
		{
			if(!$obj->isValid($array))
			{
				return FALSE;
			}
		}

		return TRUE;
	}

	/**
	* Modifie l'attribut indiquant si la protection contre le HTML est activée ou non
	*
	* @var bool $protect
	* @return bool
	*/
	public function protectHtml($protect)
	{
		return ($this->protectHtml = (bool) $protect);
	}

	/**
	*
	* Appelle la méthode getError de chaque objet ecormElement stocké dans le tableau element
	*
	* @return string		Les erreurs rencontrées à la soumission du formulaire
	*/
	public function errors()
	{
		$out = '';
		foreach($this->elements as $obj)
		{
			$out .= $obj->getError();
		}
		return $out;
	}

	/**
	*
	* Pré-rempli les champs du formulaires avec les données de l'array
	* @var array array		L'array d'où les valeurs sortent (le plus souvent $_POST ou $_GET)
	*/
	public function pre(Array $array)
	{
		foreach($this->elements as $obj)
		{
      $var = "";
      if(array_key_exists($obj->getName(), $array))
        $var = $array[$obj->getName()];

			if(isset($var))
			{
				$obj->value($var);
				$obj->defaultChoice($var);
			}
		}
	}

	/**
	*
	* Appelle la méthode getError de chaque objet ecFormElement stocké dans le tableau element
	*
	* @multiple var string/array 		Les noms des champs dont la valeur est à récupérer
	* @return array/string					Array des valeurs concernées, string si une seule valeur demandée
	*/
	public function getCleanedData($param)
	{
		$cleaned_data = array();
		$out = '';

		if($this->protectHtml)
		{
			$_POST = array_map('htmlspecialchars', $_POST);
			$_GET = array_map('htmlspecialchars', $_GET);
		}

		if(is_array($param) && func_num_args()==1)
		{
			foreach($param as $name)
			{
				$cleaned_data[] = (isset($_POST[$name])) ? $_POST[$name] : NULL;
			}
		}
		elseif(!is_array($param) && func_num_args()==1)
		{
			return $_POST[$param];
		}
		else
		{
			foreach(func_get_args() as $name)
			{
				$cleaned_data[] = (isset($_POST[$name])) ? $_POST[$name] : NULL;
			}
		}
		return $cleaned_data;
	}
}
